/*
 * Copyright (C) 2011 Jake Wharton
 * Copyright (C) 2011 Patrik Akerfeldt
 * Copyright (C) 2011 Francisco Figueiredo Jr.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.letv.android.client.view.title;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;

import com.letv.android.young.client.R;

/**
 * A TitlePageIndicator is a PageIndicator which displays the title of left view
 * (if exist), the title of the current select view (centered) and the title of
 * the right view (if exist). When the user scrolls the ViewPager then titles
 * are also scrolled.
 */
public class TitlePageIndicator extends View implements PageIndicator {

	private ViewPager mViewPager;
	private ViewPager.OnPageChangeListener mListener;
	private TitleProvider mTitleProvider;
	private int mCurrentPage;
	private int mCurrentOffset;
	private int mScrollState;
	private final Paint mPaintText = new Paint();
	ArrayList<RectF> list = new ArrayList<RectF>();

	public TitlePageIndicator(Context context) {
		this(context, null);
	}

	public TitlePageIndicator(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mPaintText.setTextSize(21 * getResources().getDisplayMetrics().density);
		mPaintText.setColor(getResources().getColor(R.color.letv_color_ff393939));
		mPaintText.setAntiAlias(true);
	}

	/**
	 * 设置text的颜色和大小
	 * 
	 * @param colorId
	 * @param textSize
	 */
	public void setTextStyle(int colorId, int textSize) {
		mPaintText.setTextSize(textSize * getResources().getDisplayMetrics().density);
		mPaintText.setColor(getResources().getColor(colorId));
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (mViewPager == null) {
			return;
		}
		final int count = mViewPager.getAdapter().getCount();
		if (count == 0) {
			return;
		}

		ArrayList<RectF> bounds = calculateAllBounds(mPaintText);
		final int boundsSize = bounds.size();

		if (mCurrentPage >= boundsSize) {
			setCurrentItem(boundsSize - 1);
			return;
		}
		for (int i = 0; i < count; i++) {
			RectF bound = bounds.get(i);
			canvas.drawText(mTitleProvider.getTitle(i), bound.left, bound.bottom * 0.82f, mPaintText);
		}
	}

	private ArrayList<RectF> calculateAllBounds(Paint paint) {
		final int count = mViewPager.getAdapter().getCount();

		RectF fr0 = list.get(mCurrentPage);
		// LogInfo.log("lhz", "mCurrentPage:"+mCurrentPage);
		if (mCurrentPage + 1 < count) {
			RectF fr1 = list.get(mCurrentPage + 1);
			float width = fr0.right - fr0.left;

			mCurrentOffset = (int) Math.floor((mCurrentOffset * width / 1000000) + 0.5f);

			// LogInfo.log("lhz","mCurrentOffset:"+mCurrentOffset);
			// LogInfo.log("lhz","width:"+width);
			// LogInfo.log("lhz","fr0.right - fr0.left:"+(fr0.right - fr0.left));
			// LogInfo.log("lhz","fr1.right - fr1.left:"+(fr1.right - fr1.left));
			if (mCurrentOffset != 0) {
				getLayoutParams().width = (int) (fr0.right - fr0.left)
						+ (int) (mCurrentOffset / width * ((fr1.right - fr1.left) - (fr0.right - fr0.left)));
				requestLayout();
				// LogInfo.log("lhz","getLayoutParams().width:"+(getLayoutParams().width));
				// LogInfo.log("lhz","getWidth():"+(getWidth()));
			}
		}

		if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
			getLayoutParams().width = (int) (fr0.right - fr0.left);
			requestLayout();
		}

		if (mCurrentOffset != 0 || mScrollState == ViewPager.SCROLL_STATE_IDLE) {
			float fw = (fr0.right - fr0.left);
			float fh = (fr0.bottom - fr0.top);
			fr0.left = -mCurrentOffset;
			fr0.right = fr0.left + fw;
			fr0.top = 0;
			fr0.bottom = fh;
		}

		RectF fr = fr0;
		for (int i = mCurrentPage - 1; i >= 0; i--) {
			RectF bounds = list.get(i);
			float w = (bounds.right - bounds.left);
			float h = (bounds.bottom - bounds.top);

			bounds.right = fr.left;
			bounds.left = bounds.right - w;
			bounds.top = 0;
			bounds.bottom = h;

			fr = bounds;
		}

		fr = fr0;
		for (int i = mCurrentPage + 1; i < count; i++) {
			RectF bounds = list.get(i);
			float w = (bounds.right - bounds.left);
			float h = (bounds.bottom - bounds.top);

			bounds.left = fr.right;
			bounds.right = bounds.left + w;
			bounds.top = 0;
			bounds.bottom = h;

			fr = bounds;
		}

		return list;
	}

	private RectF calcBounds(int index, Paint paint) {
		RectF bounds = new RectF();
		bounds.right = paint.measureText(mTitleProvider.getTitle(index));
		bounds.bottom = paint.descent() - paint.ascent();
		return bounds;
	}

	@Override
	public void setViewPager(ViewPager view) {
		if (view == null) {
			list.clear();
			mViewPager = null;
			mListener = null;
			mTitleProvider = null;
			mCurrentPage = 0;
			mCurrentOffset = 0;
			mScrollState = 0;
		} else {
			final PagerAdapter adapter = view.getAdapter();
			if (adapter == null) {
				throw new IllegalStateException("ViewPager does not have adapter instance.");
			}
			if (!(adapter instanceof TitleProvider)) {
				throw new IllegalStateException(
						"ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
			}
			mViewPager = view;
			mViewPager.setOnPageChangeListener(this);
			mTitleProvider = (TitleProvider) adapter;

			final int count = mViewPager.getAdapter().getCount();

			for (int i = 0; i < count; i++) {
				RectF fr = calcBounds(i, mPaintText);
				list.add(fr);
			}
			/**
			 * 先relayout indicator的宽高
			 */
			// LogInfo.log("lhz", "mCurrentPage:"+mCurrentPage);
			RectF mCurFr = list.get(mCurrentPage);
			getLayoutParams().width = (int) (mCurFr.right - mCurFr.left);
			getLayoutParams().height = (int) (mCurFr.bottom - mCurFr.top);
			requestLayout();
			invalidate();
		}
	}

	public void setViewPagerOnly(ViewPager view) {
		if (view == null) {
			list.clear();
			mViewPager = null;
			mListener = null;
			mTitleProvider = null;
			mCurrentPage = 0;
			mCurrentOffset = 0;
			mScrollState = 0;
		} else {
			final PagerAdapter adapter = view.getAdapter();
			if (adapter == null) {
				throw new IllegalStateException("ViewPager does not have adapter instance.");
			}
			if (!(adapter instanceof TitleProvider)) {
				throw new IllegalStateException(
						"ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
			}
			mViewPager = view;
			mTitleProvider = (TitleProvider) adapter;

			final int count = mViewPager.getAdapter().getCount();

			for (int i = 0; i < count; i++) {
				RectF fr = calcBounds(i, mPaintText);
				list.add(fr);
			}
			/**
			 * 先relayout indicator的宽高
			 */
			RectF mCurFr = list.get(mCurrentPage);
			getLayoutParams().width = (int) (mCurFr.right - mCurFr.left);
			getLayoutParams().height = (int) (mCurFr.bottom - mCurFr.top);
			requestLayout();
			invalidate();
		}
	}

	@Override
	public void setViewPager(ViewPager view, int initialPosition) {
		setViewPager(view);
		setCurrentItem(initialPosition);
	}

	@Override
	public void notifyDataSetChanged() {
		invalidate();
	}

	@Override
	public void setCurrentItem(int item) {
		if (mViewPager == null) {
			throw new IllegalStateException("ViewPager has not been bound.");
		}
		mViewPager.setCurrentItem(item);
		mCurrentPage = item;
		invalidate();
	}

	@Override
	public void onPageScrollStateChanged(int state) {
		mScrollState = state;

		if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
			invalidate();
		}
		if (mListener != null) {
			mListener.onPageScrollStateChanged(state);
		}
	}

	@Override
	public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
		mCurrentPage = position;
		// LogInfo.log("lhz", "positionOffset:"+positionOffset);
		mCurrentOffset = (int) (positionOffset * 1000000);
		invalidate();

		if (mListener != null) {
			mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
		}
	}

	@Override
	public void onPageSelected(int position) {
		if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
			mCurrentPage = position;
			if (list.size() > mCurrentPage) {
				/**
				 * 先relayout indicator的宽高
				 */
				RectF mCurFr = list.get(mCurrentPage);
				getLayoutParams().width = (int) (mCurFr.right - mCurFr.left);
				getLayoutParams().height = (int) (mCurFr.bottom - mCurFr.top);
				requestLayout();
				invalidate();
			}
		}

		if (mListener != null) {
			mListener.onPageSelected(position);
		}

	}

	@Override
	public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
		mListener = listener;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
		final int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);

		setMeasuredDimension(measuredWidth, measuredHeight);
	}

}
